/*
 * WangXiaochen only
 */
package com.naivesoft.lottery.widget;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.naivesoft.lottery.R;
import com.naivesoft.lottery.util.DisplayUtil;
import com.naivesoft.lottery.util.RandomBalls;
import com.naivesoft.lottery.util.StaticGridView;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;

/**
 * A lottery ball panel that prompts user for numbers. 
 * @author naive
 *
 */
public class BallPannel extends LinearLayout {

	public interface OnCheckedBallChangeListener {
		void onCheckedBallChange(List<Integer> redBalls, List<Integer> blueBalls);
	}
	
	public interface OnFinishChooseBallsListener {
		void onFinishChooseBalls(List<Integer> redBalls, List<Integer> blueBalls);
	}

	private final static int DEFAULT_MAX_RED_BALL_COUNT = 33;
	private final static int DEFAULT_MAX_RED_BALL_CHECKED = 20;
	private final static int DEFAULT_MIN_RED_BALL_CHECKED = 6;
	
	private final static int DEFAULT_MAX_BLUE_BALL_COUNT =16;
	private final static int DEFAULT_MAX_BLUE_BALL_CHECKED = 16;
	private final static int DEFAULT_MIN_BLUE_BALL_CHECKED = 1;
	
	private OnCheckedBallChangeListener mOnCheckedBallChangeCallBack;
	private OnFinishChooseBallsListener mOnFinishChooseBallsCallBack;
	
	private int mMaxRedBallCount;
	private int mMaxRedBallChecked;
	private int mMinRedBallChecked;
	
	private int mMaxBlueBallCount;
	private int mMaxBlueBallChecked;
	private int mMinBlueBallChecked;
	
	private List<Integer> mRedBalls;
	private List<Integer> mBlueBalls;

	private TextView mRedBallTitle;
	private TextView mBlueBallTitle;
	
	private StaticGridView mRedBallGrid;
	private StaticGridView mBlueBallGrid;
	
	private EditText mRandomRedBallCountView;
	private EditText mRandomBlueBallCountView;
	
	private Button mRandomRedBalls;
	private Button mRandomBlueBalls;
	private Button mClearAllButton;
	private Button mConfirmButton;
	
	
	private Context context;
	
	public BallPannel(Context context) {
		this(context, null);
	}

	public BallPannel(Context context, 
			AttributeSet attrs) {
		super(context, attrs);
		
		this.context = context;
		
		LayoutInflater.from(context).inflate(R.layout.ball_pannel, this, true); 
		
		mRedBallGrid = (StaticGridView) findViewById(R.id.red_ball_grid);
		mBlueBallGrid = (StaticGridView) findViewById(R.id.blue_ball_grid);
		
		mRedBallGrid.setAdapter(new RedBallAdapter());
		mBlueBallGrid.setAdapter(new BlueBallAdapter());
		
		mRedBallTitle = (TextView) findViewById(R.id.red_ball_title);
		mBlueBallTitle = (TextView) findViewById(R.id.blue_ball_title);
		
		mRandomRedBallCountView = (EditText) findViewById(R.id.random_red_ball_count);
		mRandomBlueBallCountView = (EditText) findViewById(R.id.random_blue_ball_count);
		
		mRandomRedBalls = (Button) findViewById(R.id.ball_panel_button_random_red_balls);
		mRandomBlueBalls = (Button) findViewById(R.id.ball_panel_button_random_blue_balls);
		mClearAllButton = (Button) findViewById(R.id.ball_panel_button_clear);
		mConfirmButton = (Button) findViewById(R.id.ball_panel_button_confirm);
		
		initialBalls();
		initialTitles();
		initialButtons();
	}
	
	public void setOnCheckedBallChangeListener (OnCheckedBallChangeListener listener) {
		mOnCheckedBallChangeCallBack = listener;
	}
	
	public void setOnFinishChooseBallsListener (OnFinishChooseBallsListener listener) {
		mOnFinishChooseBallsCallBack = listener;
	}
	
	public void clearAllBalls() {
		clearRedBalls();
		clearBlueBalls();
		
		if (mOnCheckedBallChangeCallBack != null) {
			mOnCheckedBallChangeCallBack.onCheckedBallChange(mRedBalls, mBlueBalls);
		}
	}
	
	public void clearRedBalls() {
		mRedBalls.clear();
		
		for (int i = 0; i < mRedBallGrid.getCount(); i++) {
			((ToggleButton) mRedBallGrid.getChildAt(i)).setChecked(false);
		}
	}
	
	public void clearBlueBalls() {
		mBlueBalls.clear();
		
		for (int i = 0; i < mBlueBallGrid.getCount(); i++) {
			((ToggleButton) mBlueBallGrid.getChildAt(i)).setChecked(false);
		}
	}
	
	public void checkRedBalls(List<Integer> redBalls) {
		clearRedBalls();

		for (int i = 0; i < mRedBallGrid.getCount(); i++) {
			if (redBalls.contains(Integer.valueOf(i + 1))) {
				((ToggleButton) mRedBallGrid.getChildAt(i)).setChecked(true);
				mRedBalls.add(new Integer(i+1));
			}
		}
		
		if (mOnCheckedBallChangeCallBack != null) {
			mOnCheckedBallChangeCallBack.onCheckedBallChange(mRedBalls, mBlueBalls);
		}
	}
	
	public void checkBlueBalls(List<Integer> blueBalls) {
		clearBlueBalls();
		
		for (int i = 0; i < mBlueBallGrid.getCount(); i++) {
			if (blueBalls.contains(Integer.valueOf(i + 1))) {
				((ToggleButton) mBlueBallGrid.getChildAt(i)).setChecked(true);
				mBlueBalls.add(new Integer(i+1));
			}
		}
		
		if (mOnCheckedBallChangeCallBack != null) {
			mOnCheckedBallChangeCallBack.onCheckedBallChange(mRedBalls, mBlueBalls);
		}
	}
	
	public void setMaxRedBallChecked(int maxRedBallChecked) {
		mMaxRedBallChecked = maxRedBallChecked;
		
		if (mMaxRedBallChecked == mMinRedBallChecked) {
			setRedBallTitle(String.format(
					context.getString(R.string.ball_panel_red_ball_title), mMinRedBallChecked));
		}
	}
	
	public void setMaxBlueBallChecked(int maxBlueBallChecked) {
		mMaxBlueBallChecked = maxBlueBallChecked;
		
		if (mMaxBlueBallChecked == mMinBlueBallChecked) {
			setBlueBallTitle(String.format(
					context.getString(R.string.ball_panel_blue_ball_title), mMinBlueBallChecked));
		}
	}
	
	public void setRedBallTitle(CharSequence title) {
		mRedBallTitle.setText(title);
	}
	
	public void setBlueBallTitle(CharSequence title) {
		mBlueBallTitle.setText(title);
	}
	
	private void initialBalls() {
		mMaxRedBallCount = DEFAULT_MAX_RED_BALL_COUNT;
		mMaxRedBallChecked = DEFAULT_MAX_RED_BALL_CHECKED;
		mMinRedBallChecked = DEFAULT_MIN_RED_BALL_CHECKED;
		mMaxBlueBallCount = DEFAULT_MAX_BLUE_BALL_COUNT;
		mMaxBlueBallChecked = DEFAULT_MAX_BLUE_BALL_CHECKED;
		mMinBlueBallChecked = DEFAULT_MIN_BLUE_BALL_CHECKED;
		
		mRedBalls = new ArrayList<Integer>();
		mBlueBalls = new ArrayList<Integer>();
	}
	
	private void initialTitles() {
		mRedBallTitle.setText(
				String.format(
						context.getString(R.string.ball_panel_red_ball_title_min), mMinRedBallChecked));
		mBlueBallTitle.setText(
				String.format(
						context.getString(R.string.ball_panel_red_ball_title_min), mMinBlueBallChecked));
	}
	
	private void initialButtons() {
		mRandomRedBallCountView.setText("" + mMinRedBallChecked);
		mRandomBlueBallCountView.setText("" + mMinBlueBallChecked);
		
		mRandomRedBalls.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				int randomBallCount  = mMinRedBallChecked;
				if (mRandomRedBallCountView.getText() != null 
						&& mRandomRedBallCountView.getText().toString() != null
						&& !mRandomRedBallCountView.getText().toString().equals("")) {
					
					randomBallCount = Integer.parseInt(mRandomRedBallCountView.getText().toString());
					if (randomBallCount > mMaxRedBallCount) {
						mRandomRedBallCountView.setText("" + mMaxRedBallCount);
						randomBallCount = mMaxRedBallCount;
					}
				} else {
					mRandomRedBallCountView.setText("" + mMinRedBallChecked);
					randomBallCount = mMinRedBallChecked;;
				}
				checkRedBalls(RandomBalls.getRandomBalls(mMaxRedBallCount, randomBallCount));
			}
		});
		
		mRandomBlueBalls.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				int randomBallCount = mMinBlueBallChecked;
				if (mRandomBlueBallCountView.getText() != null 
						&& mRandomBlueBallCountView.getText().toString() != null
						&& !mRandomBlueBallCountView.getText().toString().equals("")) {
					
					randomBallCount = Integer.parseInt(mRandomBlueBallCountView.getText().toString());
					if (randomBallCount > mMaxBlueBallCount) {
						mRandomBlueBallCountView.setText("" + mMaxBlueBallCount);
						randomBallCount = mMaxBlueBallCount;
					}
				} else {
					mRandomBlueBallCountView.setText("" + mMinBlueBallChecked);
					randomBallCount = mMinBlueBallChecked;
				}
				checkBlueBalls(RandomBalls.getRandomBalls(mMaxBlueBallCount, randomBallCount));
			}
		});
		
		mClearAllButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				clearAllBalls();
			}
		});
		
		mConfirmButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				int selectedRedBallCount = mRedBalls.size();
				int selectedBlueBallCount = mBlueBalls.size();
				String errorText = "";
				
				if (selectedRedBallCount > mMaxRedBallChecked) {
					errorText = String.format(
							context.getString(R.string.ball_panel_red_ball_title_max), mMaxRedBallChecked);
					Toast.makeText(context, errorText, Toast.LENGTH_SHORT).show();
					return ;
				} else if (selectedRedBallCount < mMinRedBallChecked) {
					errorText = String.format(
							context.getString(R.string.ball_panel_red_ball_title_min), mMinRedBallChecked);
					Toast.makeText(context, errorText, Toast.LENGTH_SHORT).show();
					return ;
				}
				
				if (selectedBlueBallCount > mMaxBlueBallChecked) {
					errorText = String.format(
							context.getString(R.string.ball_panel_blue_ball_title_max), mMaxBlueBallChecked);
					Toast.makeText(context, errorText, Toast.LENGTH_SHORT).show();
					return ;
				} else if (selectedBlueBallCount < mMinBlueBallChecked) {
					errorText = String.format(
							context.getString(R.string.ball_panel_blue_ball_title_min), mMinBlueBallChecked);
					Toast.makeText(context, errorText, Toast.LENGTH_SHORT).show();
					return ;
				}
				
				if (mOnFinishChooseBallsCallBack != null) {
					mOnFinishChooseBallsCallBack.onFinishChooseBalls(mRedBalls, mBlueBalls);
				}
			}
		});
	}
	
	private class RedBallAdapter extends BaseAdapter {
        public RedBallAdapter() {
        }

        public View getView(int position, View convertView, ViewGroup parent) {
        	ToggleButton redBall;

            if (convertView == null) {
            	redBall = (ToggleButton) LayoutInflater.from(getContext()).inflate(R.layout.ball_pannel_red_ball, null);
                redBall.setId(position + 1);
                redBall.setTextOn(String.format("%02d", (position + 1)));
                redBall.setTextOff(String.format("%02d", (position + 1)));
                redBall.setChecked(redBall.isChecked());
                redBall.setLayoutParams(new GridView.LayoutParams(
                		DisplayUtil.dip2px(context, 24),
                		DisplayUtil.dip2px(context, 26)));
                redBall.setOnClickListener(redBallClickListener);
            } else {
                redBall = (ToggleButton) convertView;
            }

            return redBall;
        }

        public final int getCount() {
            return mMaxRedBallCount;
        }

        public final Object getItem(int position) {
            return null;
        }

        public final long getItemId(int position) {
            return position + 1;
        }
    }
	
	private class BlueBallAdapter extends BaseAdapter {
        public BlueBallAdapter() {
        }

        public View getView(int position, View convertView, ViewGroup parent) {
        	ToggleButton blueBall;

            if (convertView == null) {
            	blueBall = (ToggleButton) LayoutInflater.from(getContext()).inflate(R.layout.ball_pannel_blue_ball, null);
                blueBall.setId(position + 1);
                blueBall.setTextOn(String.format("%02d", (position + 1)));
                blueBall.setTextOff(String.format("%02d", (position + 1)));
                blueBall.setChecked(blueBall.isChecked());
                blueBall.setLayoutParams(new GridView.LayoutParams(
                		DisplayUtil.dip2px(context, 24),
                		DisplayUtil.dip2px(context, 26)));
                blueBall.setOnClickListener(blueBallClickListener);
            } else {
                blueBall = (ToggleButton) convertView;
            }

            return blueBall;
        }

        public final int getCount() {
            return mMaxBlueBallCount;
        }

        public final Object getItem(int position) {
            return null;
        }

        public final long getItemId(int position) {
            return position + 1;
        }
    }
	
	private View.OnClickListener redBallClickListener = new View.OnClickListener() {
		@Override
		public void onClick(View v) {
			if (mRedBalls.contains(new Integer(v.getId()))) {
				mRedBalls.remove(new Integer(v.getId()));
			} else {
				mRedBalls.add(new Integer(v.getId()));
			}
			Collections.sort(mRedBalls);
			if (mOnCheckedBallChangeCallBack != null) {
				mOnCheckedBallChangeCallBack.onCheckedBallChange(mRedBalls, mBlueBalls);
			}
		}
	};
	
	private View.OnClickListener blueBallClickListener = new View.OnClickListener() {
		@Override
		public void onClick(View v) {
			if (mBlueBalls.contains(new Integer(v.getId()))) {
				mBlueBalls.remove(new Integer(v.getId()));
			} else {
				mBlueBalls.add(new Integer(v.getId()));
			}
			Collections.sort(mBlueBalls);
			if (mOnCheckedBallChangeCallBack != null) {
				mOnCheckedBallChangeCallBack.onCheckedBallChange(mRedBalls, mBlueBalls);
			}
		}
	};
	
}
